package com.mentalhealthplatform.global.rbac.service.entity;

import com.mentalhealthplatform.global.rbac.dto.request.EndpointRequest;
import com.mentalhealthplatform.global.rbac.model.Endpoint;
import com.mentalhealthplatform.global.rbac.model.Permission;
import com.mentalhealthplatform.global.rbac.model.Role;
import com.mentalhealthplatform.global.rbac.repository.EndpointRepository;
import com.mentalhealthplatform.global.rbac.repository.PermissionRepository;
import com.mentalhealthplatform.global.rbac.repository.RoleRepository;
import com.mentalhealthplatform.global.rbac.service.relation.MenuPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Service
public class PermissionService {

    @Autowired
    private PermissionRepository permissionRepository;

    @Autowired
    private RoleRepository roleRepository;

    @Autowired
    private MenuPermissionService menuPermissionService;

    @Autowired
    private EndpointRepository endpointRepository;





    /**
     * 检查请求路径是否匹配数据库中的端点路径（包括占位符）
     *
     * @param endpointPath 数据库中的端点路径，可能包含占位符（如 /users/{userId}）
     * @param requestPath  请求路径
     * @return 如果匹配，则返回 true；否则返回 false
     */
    private boolean pathMatchesWithPlaceholders(String endpointPath, String requestPath) {
        // 将占位符（如 {userId}）转换为正则表达式部分（[^/]+）
        String regex = endpointPath.replaceAll("\\{[^/]+\\}", "[^/]+");

        // 在路径的起点和终点添加 ^ 和 $ 来确保完整匹配
        regex = "^" + regex + "$";

        return requestPath.matches(regex);
    }


    /**
     * 创建新权限
     *
     * @param name 权限名称
     * @return 创建的权限对象
     */
    public Permission createPermission(String name) {
        Permission permission = new Permission(name);
        return permissionRepository.save(permission);
    }


    /**
     * 为角色分配权限
     *
     * @param roleId       角色 ID
     * @param permissionId 权限 ID
     */
    public void assignPermissionToRole(long roleId, long permissionId) {
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new RuntimeException("Role not found"));
        Permission permission = permissionRepository.findById(permissionId)
                .orElseThrow(() -> new RuntimeException("Permission not found"));

        role.getPermissions().add(permission);
        roleRepository.save(role);
    }

    /**
     * 获取角色的所有权限
     *
     * @param roleId 角色 ID
     * @return 角色的权限列表
     */
    public Set<Permission> getPermissionsForRole(Long roleId) {
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new RuntimeException("Role not found"));
        return new HashSet<>(role.getPermissions());
    }



    /**
     * 将权限分配给角色。
     *
     * @param roleId 角色的唯一标识符（ID）
     * @param permissionId 权限的唯一标识符（ID）
     * @return 更新后的角色对象，包含分配的新权限
     * @throws RuntimeException 如果角色或权限未找到，抛出运行时异常
     */
    public Role grantPermissionToRole(Long roleId, Long permissionId) {
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new RuntimeException("Role not found"));
        Permission permission = permissionRepository.findById(permissionId)
                .orElseThrow(() -> new RuntimeException("Permission not found"));

        role.getPermissions().add(permission);
        return roleRepository.save(role);
    }

    /**
     * 从角色中回收权限
     *
     * @param roleId 角色的唯一标识符（ID）
     * @param permissionId 权限的唯一标识符（ID）
     * @throws RuntimeException 如果角色或权限未找到，抛出运行时异常
     */
    public void revokePermissionFromRole(Long roleId, Long permissionId) {
        Role role = roleRepository.findById(roleId)
                .orElseThrow(() -> new RuntimeException("Role not found"));
        Permission permission = permissionRepository.findById(permissionId)
                .orElseThrow(() -> new RuntimeException("Permission not found"));

        // 从角色的权限集合中移除指定权限
        if (role.getPermissions().contains(permission)) {
            role.getPermissions().remove(permission);
            roleRepository.save(role);
        } else {
            throw new RuntimeException("Permission not assigned to this role");
        }
    }

    // 添加新的 API 端点
    public void addEndpoint(EndpointRequest endpointRequest) {
        Endpoint endpoint = new Endpoint();
        endpoint.setPath(endpointRequest.getPath());
        endpoint.setMethod(endpointRequest.getMethod());
        //endpoint.setAccessLevel(endpointRequest.getAccessLevel());
        endpoint.setAllowAnonymous(endpointRequest.isAllowAnonymous());
        endpointRepository.save(endpoint);
    }

    // 删除指定的 API 端点
    public void deleteEndpoint(Long endpointId) {
        Optional<Endpoint> endpoint = endpointRepository.findById(endpointId);
        if (endpoint.isPresent()) {
            endpointRepository.delete(endpoint.get());
        } else {
            throw new RuntimeException("Endpoint not found");
        }
    }

    // 返回所有的 API 端点
    public List<Endpoint> getAllEndpoints() {
        return endpointRepository.findAll();
    }



    ////////////////////////////////////////////////////////
    public List<Permission> getAllPermissions() {
        return permissionRepository.findAll();
    }

    public Optional<Permission> getPermissionById(Long id) {
        return permissionRepository.findById(id);
    }

    public Permission createPermissionIfNotFound(String name,String displayName,Integer orderNum, Endpoint endpoint) {
        // 尝试查找是否已存在对应的权限
        Optional<Permission> existingPermission = permissionRepository.findByIdentifier(name);

        // 如果权限已存在，直接返回
        if (existingPermission.isPresent()) {
            return existingPermission.get();
        }

        // 如果权限不存在，创建并保存新的权限
        Permission permission = new Permission();
        permission.setIdentifier(name);
        permission.setDisplayName(displayName);
        permission.setOrderNum(orderNum);

        return permissionRepository.save(permission);
    }




    public Permission updatePermission(Long id, String name, Endpoint endpoint) {
        Permission permission = permissionRepository.findById(id).orElseThrow(() -> new RuntimeException("Permission not found"));
        permission.setIdentifier(name);
        return permissionRepository.save(permission);
    }

    public void deletePermission(Long id) {
        Permission permission = permissionRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("Permission with ID " + id + " not found"));

        permissionRepository.deleteById(id);
    }


    public void togglePermissionStatus(Long id) {
        Permission permission = permissionRepository.findById(id).orElseThrow(() -> new RuntimeException("Permission not found"));
        permission.toggleStatus();
        permissionRepository.save(permission);
    }

}
